<?php

use App\Http\ApiResponse;
use App\Http\Services\LoginService;
use App\Http\Services\Messages\SendMessageService;
use App\Http\Services\WechatService;
use App\Models\Config;
use App\Models\ParkDeliverTime;
use App\Repositories\Manage\UserRepository;
use phpDocumentor\Reflection\Types\Boolean;
use Symfony\Component\VarDumper\VarDumper;

if (!function_exists('C')) {  //获取配置文件参数
    function C($key)
    {
        return Config::getValue($key);
    }
}

// 发送公众号消息模板
if (!function_exists('sendTemplateMsg')) {
    function sendTemplateMsg($openId, $type, $data, $msg_type = "")
    {
        if (!$openId || !$type || !$msg_type) return "";
//        Log::channel("log")->debug($data);
        return app(WechatService::class)->sendTemplateMessage($openId, $type, $data, $msg_type);
    }
}

/*
 * 发送订阅消息
 */
if (!function_exists('sendSubscribeTemplateMsg')) {
    function sendSubscribeTemplateMsg($weappOpenId, $type, $data)
    {
        if (!$weappOpenId || !$type) return "";
        return app(SendMessageService::class)->send($weappOpenId, $type, $data);
    }
}

if (!function_exists('image_path')) {
    function image_path($uri, $width = 500, $height = 500)
    {
        if ($uri && strpos($uri, "http") !== false) {
            return $uri;
        }

        if ($width && !$height) {
            return env("IMG_DOMAIN") . $uri . '?imageMogr2/thumbnail/' . $width . 'x';
        }

        if ($height && !$width) {
            return env("IMG_DOMAIN") . $uri . '?imageMogr2/thumbnail/x' . $height;
        }

        if ($height && $width) {
            return env("IMG_DOMAIN") . $uri . '?imageMogr2/scrop/' . $width . 'x' . $height . '/crop/' . $width . 'x' . $height . '/gravity/center';
        }

        return env("IMG_DOMAIN") . $uri;

    }
}

if (!function_exists('filterPaginateData')) {
    /**
     * 对Paginate结果过滤
     *
     * @param [array] $rs
     * @return array
     */
    function filterPaginateData($rs)
    {
        return [
            'total' => $rs['total'],
            'last_page' => $rs['last_page'],
            'items' => $rs['data'],
            'current_page' => $rs['current_page']
        ];
    }
}

/**
 * 对Paginate结果过滤
 *
 * @param [array] $rs
 * @return array
 */
function filterPaginateData1($rs)
{
    return [
        'total' => $rs['total'],
        'last_page' => $rs['last_page'],
        'data' => $rs['data'],
        'current_page' => $rs['current_page']
    ];
}

if (!function_exists('formatBytes')) {
    function formatBytes($bytes)
    {
        if ($bytes >= 1073741824) {
            $bytes = round($bytes / 1073741824 * 100) / 100 . 'GB';
        } elseif ($bytes >= 1048576) {
            $bytes = round($bytes / 1048576 * 100) / 100 . 'MB';
        } elseif ($bytes >= 1024) {
            $bytes = round($bytes / 1024 * 100) / 100 . 'KB';
        } else {
            $bytes = $bytes . 'Bytes';
        }
        return $bytes;
    }
}
if (!function_exists('sql')) {
    /**
     * 监听数据库操作
     *
     * @param boolean $echo 是否直接打印；如果为false不直接打印，将SQL写入$_SERVER['sql]
     * @return void
     */
    function sql($echo = true, $path = '/opt/logs/bsbly_mini_api')
    {
        DB::listen(function ($query) use ($echo) {
            $bindings = $query->bindings;
            $sql = $query->sql;

            foreach ($bindings as $replace) {
                $value = is_numeric($replace) ? $replace : "'" . $replace . "'";
                $sql = preg_replace('/\?/', $value, $sql, 1);
            }

            if ($echo) {
                $_SERVER['sql'][] = $sql;
                file_put_contents($path . '/sql_' . date('d') . '.log', date('Y-m-d H:i:s') . ' ' . $sql . "\n", 8);
//                Log::channel("log")->debug("sql: " . $sql);
            } else {
                echo $sql, "\r\n";
            }
        });
    }
}

/**
 * @return array
 * 省份信息
 */
if (!function_exists('getChinaProvince')) {
    function getChinaProvince()
    {
        return [
            "北京", "天津", "河北", "山西", "内蒙古", "辽宁", "吉林", "黑龙江", "上海", "江苏", "浙江", "安徽", "福建", "江西",
            "山东", "河南", "湖北", "湖南", "广东", "广西", "海南", "重庆", "四川", "贵州", "云南", "西藏", "陕西", "甘肃", "青海",
            "宁夏", "新疆", "台湾", "香港", "澳门", "海外",
        ];
    }
}

function check_province($address)
{
    $province = array('江苏', '浙江', '安徽', '河北', '山西', '辽宁', '吉林', '黑龙江', '福建', '江西', '山东', '河南', '湖北', '湖南', '广东', '海南', '四川', '贵州', '云南', '陕西', '甘肃', '青海', '内蒙古', '广西', '西藏', '宁夏', '新疆', '老乡', '省份', '不限');
    if (in_array($address, $province)) {
        return false;
    }
    return true;
}

/**
 * 字符串截取，支持中文和其他编码
 * @static
 * @access public
 * @param string $str 需要转换的字符串
 * @param string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start, $length, $charset = "utf-8", $suffix = true)
{
    if (function_exists("mb_substr")) {
        $slice = mb_substr($str, $start, $length, $charset);
    } elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if (false === $slice) {
            $slice = '';
        }
    } else {
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice . '...' : $slice;
}

/**
 * [获取在线预览office文件地址]
 * @param  [type] $url [传入的url地址]
 * @return [type]      [预览的url地址]
 */
function getViewUrl($url, $full_url = false)
{
    $file_name = end(explode('/', $url));
    $ext_name = strtolower(end(explode('.', $file_name)));
    if (in_array($ext_name, ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx'])) {
        $extend_url = $full_url ? $url : $_SERVER['HTTP_HOST'] . $url;
        $url = 'https://view.officeapps.live.com/op/view.aspx?src=' . $extend_url;
    }
    return $url;
}

if (!function_exists('get_sort_link')) {
    function get_sort_link($sort, $field, $slot)
    {
        $request_sort = request()->sort;
        $request_sort = explode('.', $request_sort);
        $sort_key = $sort['sort'][0];
        $sort_param = $request_sort == '' ? $sort['sort'][2] : 'id.desc';
        if ($request_sort[0] != 'id') {
            if ($request_sort[1] == 'asc') {
                $sort_param = $field . '.desc';
            } else {
                $sort_param = $field . '.asc';
            }
        }
        if ($sort_key == $field) {
            if ($request_sort == '') {
                $icon = '<i class="fa fa-sort"></i>';
            } elseif ($sort['sort'][1] == 'desc') {
                $icon = '<i class="fa fa-sort-down"></i>';
            } elseif ($sort['sort'][1] == 'asc') {
                $icon = '<i class="fa fa-sort-up"></i>';
            }
        } else {
            $icon = '<i class="fa fa-sort"></i>';
        }
        $href = $sort['sort_url'] . '&sort=' . $sort_param;

        $a = <<<EOF
        <a href="$href">
            $slot $icon
        </a>
EOF;
        echo $a;
    }
}


/**
 * @param  [type] $img_url  ['传入的图片地址,必须全地址']
 * @return [type] $img ['画布']
 */

if (!function_exists('gd_image_create')) {
    function gd_image_create($img_url)
    {
        $base = substr(strrchr(strtolower($img_url), '.'), 1);
        $base = explode('?', $base);
        $base = $base[0];
        switch ($base) {
            case 'gif':
                $img = imagecreatefromgif($img_url);
                break;
            case 'jpeg':
                $img = imagecreatefromjpeg($img_url);
                break;
            case 'jpg':
                $img = imagecreatefromjpeg($img_url);
                break;
            case 'png':
                $img = imagecreatefrompng($img_url);
                break;
            default:
                die('文件类型不正确');
        }; //加载背景图
        return $img;
    }
}

/**
 * @param  [type] $date  ['传入的时间']
 * @return 中文月份
 */
if (!function_exists('cnmonth')) {
    function cnmonth($date)
    {
        $month = date('m', strtotime($date));
        $arr = array('1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月');
        return $arr[$month - 1];
    }
}

if (!function_exists('getPreviewImage')) {
    function getPreviewImage($url, $width = 0, $height = 0)
    {
        return image_path($url, $width, $height);
    }
}

if (!function_exists('replacePrevieImages')) {
    /**
     * 过滤对象或数组，补充图片地址
     * 支持page对象、page数组、列表对象、用户对象
     *
     * @param array|Illuminate\Database\Eloquent\Collection|Illuminate\Support\Collection|Illuminate\Pagination\LengthAwarePaginator $list
     * @param string $field
     * @return array|Illuminate\Database\Eloquent\Collection|Illuminate\Support\Collection|Illuminate\Pagination\LengthAwarePaginator
     */
    function replacePrevieImages($list, $field = 'preview_image')
    {
        if ($list[$field]) {
            $list[$field] = getPreviewImage($list[$field]);
        } elseif ($list['data']) {
            foreach ($list['data'] as $key => $value) {
                if ($list['data'][$key][$field]) {
                    $list['data'][$key][$field] = getPreviewImage($list['data'][$key][$field]);
                }
            }
        } elseif ($list['items']) {
            foreach ($list['items'] as $key => $value) {
                if ($list['items'][$key][$field]) {
                    $list['items'][$key][$field] = getPreviewImage($list['items'][$key][$field]);
                }
            }
        } elseif ('Illuminate\Support\Collection' === get_class($list)) {
            foreach ($list as $item) {
                if ($item[$field]) {
                    $item[$field] = getPreviewImage($item[$field]);
                }
            }
        } elseif ('Illuminate\Database\Eloquent\Collection' === get_class($list)) {
            foreach ($list as $item) {
                if ($item[$field]) {
                    $item[$field] = getPreviewImage($item[$field]);
                }
            }
        } elseif ('Illuminate\Pagination\LengthAwarePaginator' === get_class($list)) {
            foreach ($list as $item) {
                if ($item[$field]) {
                    $item[$field] = getPreviewImage($item[$field]);
                }
            }
        } elseif (get_class($list) === 'object' || gettype($list) === 'array') {
            foreach ($list as &$item) {
                if ($item[$field]) {
                    $item[$field] = getPreviewImage($item[$field]);
                }
            }
        }
        return $list;
    }
}

if (!function_exists('ll')) {
    function ll(...$vars)
    {
        foreach ($vars as $v) {
            VarDumper::dump($v);
        }
    }
}

if (!function_exists('isJson')) {
    function isJson($string)
    {
        json_decode($string);
        return (json_last_error() == JSON_ERROR_NONE);
    }
}

/**
 * php防止xss攻击
 * @param $string
 * @param false $low
 * @return bool
 */
function string_remove_xss($html)
{
    preg_match_all("/\<([^\<]+)\>/is", $html, $ms);

    $searchs[] = '<';
    $replaces[] = '&lt;';
    $searchs[] = '>';
    $replaces[] = '&gt;';

    if ($ms[1]) {
        $allowtags = 'img|a|font|div|table|tbody|caption|tr|td|th|br|p|b|strong|i|u|em|span|ol|ul|li|blockquote';
        $ms[1] = array_unique($ms[1]);
        foreach ($ms[1] as $value) {
            $searchs[] = "&lt;" . $value . "&gt;";

            $value = str_replace('&amp;', '_uch_tmp_str_', $value);
            $value = string_htmlspecialchars($value);
            $value = str_replace('_uch_tmp_str_', '&amp;', $value);

            $value = str_replace(array('\\', '/*'), array('.', '/.'), $value);
            $skipkeys = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate',
                'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange',
                'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick',
                'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate',
                'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete',
                'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel',
                'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart',
                'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop',
                'onsubmit', 'onunload', 'javascript', 'script', 'eval', 'behaviour', 'expression', 'style', 'class');
            $skipstr = implode('|', $skipkeys);
            $value = preg_replace(array("/($skipstr)/i"), '.', $value);
            if (!preg_match("/^[\/|\s]?($allowtags)(\s+|$)/is", $value)) {
                $value = '';
            }
            $replaces[] = empty($value) ? '' : "<" . str_replace('&quot;', '"', $value) . ">";
        }
    }
    $html = str_replace($searchs, $replaces, $html);

    return $html;
}

//php防注入和XSS攻击通用过滤
function string_htmlspecialchars($string, $flags = null)
{
    if (is_array($string)) {
        foreach ($string as $key => $val) {
            $string[$key] = string_htmlspecialchars($val, $flags);
        }
    } else {
        if ($flags === null) {
            $string = str_replace(array('&', '"', '<', '>'), array('&amp;', '&quot;', '&lt;', '&gt;'), $string);
            if (strpos($string, '&amp;#') !== false) {
                $string = preg_replace('/&amp;((#(\d{3,5}|x[a-fA-F0-9]{4}));)/', '&\\1', $string);
            }
        } else {
            if (PHP_VERSION < '5.4.0') {
                $string = htmlspecialchars($string, $flags);
            } else {
                if (!defined('CHARSET') || (strtolower(CHARSET) == 'utf-8')) {
                    $charset = 'UTF-8';
                } else {
                    $charset = 'ISO-8859-1';
                }
                $string = htmlspecialchars($string, $flags, $charset);
            }
        }
    }

    return $string;
}

if (!function_exists('datetimeRangeParse')) {
    /**
     * 时间段解析，针对时间段选择器提交的内容进行解析，譬如:“2021-07-01 12:00 至 2021-08-01 12:00”、“2021-07-01 12:00 To 2021-08-01 12:00” \
     * 支持的时间格式:2021-07-01 12:00 至 2021-08-01 12:00 \
     *              2021-07-01 12:00:00 至 2021-08-01 12:00:00 \
     *              2021-07-01 12 至 2021-08-01 12 \
     *              2021-07-01 至 2021-08-01 \
     *              2021-07 至 2021-08
     *
     * @param string $datetime
     * @return array|null
     * 如果解析成功返回数组，结果如:\
     * [ \
     *     "2021-07-01 12:00", \
     *     "2021-08-01 12:00" \
     * ] \
     * 如果解析失败，返回null
     */
    function datetimeRangeParse($datetime)
    {
        if (preg_match('/^(\d{4}[\d:_\ -]+)[^\d]+(\d{4}[\d:_\ -]+)$/', $datetime, $matches)) {
            return [
                trim($matches[1]),
                trim($matches[2]),
            ];
        } else {
            return null;
        }
    }
}

/**
 * 处理用户登录密码
 * @param String $pwd
 * @return string
 */
function genPassword($pwd)
{
    return app(LoginService::class)->genPassword($pwd);
}

if (!function_exists('sendMessages')) {
    function sendMessages($mobile, $contents, $type = 1)
    {
        // $sign = Config::getValue("sms_sign_name");
        $apiKey = env('SMS_KEY_ID');
        $apiSecret = env('SMS_KEY_SECRET');
        $sign = env("SMS_SIGN_NAME");

        $client = new Client(
            $apiKey,
            $apiSecret
        );

        if ($type == 1) {
            $contents = $sign . $contents;
            $resData = $client->post('/sms/send',
                [
                    'mobile' => $mobile,
                    'content' => $contents
                ]);
        } else {
            $resData = $client->post('/sms/send',
                [
                    'mobile' => $mobile,
                    'content' => $contents,
                    'type' => 'voice'
                ]);
        }

        $ret = $resData->getResponseData();
        return $ret['data']['success'];
    }
}

if (!function_exists('array_get')) {
    function array_get($array, $key, $default = null)
    {
        if (is_null($key)) {
            return $array;
        }

        if (isset($array[$key])) {
            return $array[$key];
        }

        foreach (explode('.', $key) as $segment) {
            if (!is_array($array) || !array_key_exists($segment, $array)) {
                return value($default);
            }

            $array = $array[$segment];
        }
        return $array;
    }

}

if (!function_exists('starts_with')) {
    function starts_with($haystack, $needle)
    {
        $length = strlen($needle);
        return (substr($haystack, 0, $length) === $needle);
    }
}
if (!function_exists('ends_with')) {
    function ends_with($haystack, $needle)
    {
        $length = strlen($needle);
        if ($length == 0) {
            return true;
        }

        return (substr($haystack, -$length) === $needle);
    }
}

function get_column($a = array(), $column = 'id', $null = true, $column2 = null)
{
    $ret = array();
    @list($column, $anc) = preg_split('/[\s\-]/', $column, 2, PREG_SPLIT_NO_EMPTY);
    foreach ($a as $one) {
        if ($null || @$one[$column])
            $ret[] = @$one[$column] . ($anc ? '-' . @$one[$anc] : '');
    }
    return $ret;
}

/* support 2-level now  2-level将重复键的生成二维数组*/
function ass_column($a = array(), $column = 'id', $as_array = false)
{
    $two_level = func_num_args() > 2 ? true : false;
    if ($two_level) $scolumn = func_get_arg(2);

    $ret = array();
    settype($a, 'array');
    if (false == $two_level) {
        foreach ($a as $one) {
            if (is_array($one))
                $ret[@$one[$column]] = $one;
            else
                $ret[@$one->$column] = $one;
        }
    } else {
        foreach ($a as $one) {
            if (is_array($one)) {
                if (false == isset($ret[@$one[$column]])) {
                    $ret[@$one[$column]] = array();
                }
                if ($as_array) {
                    if (!in_array($one[$column], array_keys($ret))) {
                        $ret[@$one[$column]][] = $one;
                    } else {
                        $ret[@$one[$column]][] = $one;
                    }
                } else {
                    $ret[@$one[$column]][@$one[$scolumn]] = $one;
                }
            } else {
                if (false == isset($ret[@$one->$column]))
                    $ret[@$one->$column] = array();

                $ret[@$one->$column][@$one->$scolumn] = $one;
            }
        }
    }
    return $ret;
}


/**
 * 字节转换
 */
if (!function_exists('getSizeUnit')) {
    function getSizeUnit($filesize)
    {
        if ($filesize >= 1073741824) {
            //转成GB
            $filesize = round($filesize / 1073741824 * 100) / 100 . ' GB';
        } elseif ($filesize >= 1048576) {
            //转成MB
            $filesize = round($filesize / 1048576 * 100) / 100 . ' MB';
        } elseif ($filesize >= 1024) {
            //转成KB
            $filesize = round($filesize / 1024 * 100) / 100 . ' KB';
        } else {
            //不转换直接输出
            $filesize = $filesize . ' 字节';
        }
        return $filesize;
    }
}

/**
 * 验证输入的手机号码
 * @access  public
 * @param string $user_mobile 需要验证的手机号码
 * @return bool
 */
if (!function_exists('isMobile')) {
    function isMobile($user_mobile, $type = 1)
    {
        return preg_match('/^1[\d]{10}$/', $user_mobile) || preg_match('/^0[\d]{10,11}$/', $user_mobile);
    }
}

function phoneReplace($moible = "")
{
    if (!$moible)
        return "";

//    return preg_replace("/(\d{3})\d{4}(\d{4})/", "$1****$2", $moible);

    return substr_replace($moible, '****', 3, 4);
}

/**
 * 用户名首位后替换成星号
 * @param string $username
 * @return array|string|string[]
 */
function usernameReplace($username = "")
{
    return substr_replace($username, str_repeat("*", strlen($username) - 1), 1);
}


function cut_str($string, $sublen, $start = 0, $code = 'UTF-8')

{

    if ($code == 'UTF-8') {

        $pa = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|\xe0[\xa0-\xbf][\x80-\xbf]|[\xe1-\xef][\x80-\xbf][\x80-\xbf]|\xf0[\x90-\xbf][\x80-\xbf][\x80-\xbf]|[\xf1-\xf7][\x80-\xbf][\x80-\xbf][\x80-\xbf]/";

        preg_match_all($pa, $string, $t_string);
        if (count($t_string[0]) - $start > $sublen) return join('', array_slice($t_string[0], $start, $sublen));

        return join('', array_slice($t_string[0], $start, $sublen));

    } else {

        $start = $start * 2;

        $sublen = $sublen * 2;

        $strlen = strlen($string);

        $tmpstr = '';
        for ($i = 0; $i < $strlen; $i++) {

            if ($i >= $start && $i < ($start + $sublen)) {

                if (ord(substr($string, $i, 1)) > 129) {

                    $tmpstr .= substr($string, $i, 2);

                } else {

                    $tmpstr .= substr($string, $i, 1);

                }

            }

            if (ord(substr($string, $i, 1)) > 129) $i++;

        }

        //if(strlen($tmpstr)< $strlen ) $tmpstr.= "...";

        return $tmpstr;

    }

}

/**
 * 生成随机字符串
 * @param string $lenth 长度
 * @return string 字符串
 */
function get_randomstr($lenth = 6, $type = 'all')
{
    if ($type == 'num') {
        $str = '0123456789';
    } else if ($type == 'string') {
        $str = 'abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';
    } else {
        $str = '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';
    }
    return get_random_str($lenth, $str);
}

/**
 * 产生随机字符串
 *
 * @param int $length 输出长度
 * @param string $chars 可选的 ，默认为 0123456789
 * @return   string     字符串
 */
if (!function_exists('get_random_str')) {

    function get_random_str($length, $chars = '0123456789')
    {
        $hash = '';
        $max = strlen($chars) - 1;
        for ($i = 0; $i < $length; $i++) {
            $hash .= $chars[mt_rand(0, $max)];
        }
        return $hash;
    }
}

/**
 * 生成随机字符串
 * @param int $length
 * @return string
 */
function gen_salt($length = 8)
{
// 密码字符集，可任意添加你需要的字符
    $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-_ []{}<>~`+=,.;:/?|";
    $password = "";
    for ($i = 0; $i < $length; $i++) {
        $password .= $chars[mt_rand(0, strlen($chars) - 1)];
    }
    return $password;
}

function formatDate($time = '')
{
    $text = '';
    $time = is_numeric($time) ? $time : strtotime($time);
    $t = time() - $time; //时间差 （秒）
    $y = date('Y', $time) - date('Y', time());//是否跨年
    switch ($t) {
        case $t == 0:
            $text = '刚刚';
            break;
        case $t < 60:
            $text = $t . '秒前'; // 一分钟内
            break;
        case $t < 60 * 60:
            $text = floor($t / 60) . '分钟前'; //一小时内
            break;
        case $t < 60 * 60 * 24:
            $text = floor($t / (60 * 60)) . '小时前'; // 一天内
            break;
        case $t < 60 * 60 * 24 * 3:
            $text = floor($time / (60 * 60 * 24)) == 1 ? '昨天 ' . date('H:i', $time) : '前天 ' . date('H:i', $time); //昨天和前天
            break;
        case $t < 60 * 60 * 24 * 30:
            $text = date('m月d日 H:i', $time); //一个月内
            break;
        case $t < 60 * 60 * 24 * 365 && $y == 0:
            $text = date('m月d日 H:i', $time); //一年内
            break;
        default:
            $text = date('Y年m月d日 H:i', $time); //一年以前
            break;
    }
    return $text;
}

function time2string($second)
{
    $day = floor($second / (3600 * 24));
    $second = $second % (3600 * 24);//除去整天之后剩余的时间
    $hour = floor($second / 3600);
    $second = $second % 3600;//除去整小时之后剩余的时间
    $minute = floor($second / 60);
    $second = $second % 60;//除去整分钟之后剩余的时间
    //返回字符串
    return $day . '天' . $hour . '小时' . $minute . '分' . $second . '秒';
}

function nextMonday()
{
    $w = date('w', time()); //求得当前星期
    return strtotime(date('Y-m-d')) + (7 - $w + 1) * 60 * 60 * 24;
}

function is_str_has($str, $find)
{
    if (strpos($str, $find) !== false) {
        return true;
    } else {
        return false;
    }
}

/**
 * 计算两个经纬度距离
 */
function get_distance($lat1, $lng1, $lat2, $lng2)
{
    if (!$lat1 || !$lng1 || !$lng2) return "";

    $earthRadius = 6367000; //地球的近似半径（米）
    $lat1 = ($lat1 * pi()) / 180;
    $lng1 = ($lng1 * pi()) / 180;
    $lat2 = ($lat2 * pi()) / 180;
    $lng2 = ($lng2 * pi()) / 180;
    $calcLongitude = $lng2 - $lng1;
    $calcLatitude = $lat2 - $lat1;
    $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
    $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
    $calculatedDistance = round($earthRadius * $stepTwo);

    if ($calculatedDistance < 1000) {
        $result = $calculatedDistance . 'm';
    }

    if ($calculatedDistance >= 1000) {
        $result = round($calculatedDistance / 1000) . 'km';
    }

    return $result;
}

/**
 * 精确加法
 * @param [type] $a [description]
 * @param [type] $b [description]
 */
function math_add($a, $b, $scale = '2')
{
    return bcadd($a, $b, $scale);
}

function isWxAvatar($avatar, $status = 0)
{

    if (stripos($avatar, 'http') !== false) {
        return true;
    }

    if ($avatar && intval($status) == 0) { // 判断会员状态（status）
        return true;
    }

    return false;
}

const CHAR_MIX = 0;
const CHAR_NUM = 1;
const CHAR_WORD = 2;
function GenSecret($len = 6, $type = CHAR_WORD)
{
    $secret = '';
    for ($i = 0; $i < $len; $i++) {
        if (CHAR_NUM == $type) {
            if (0 == $i) {
                $secret .= chr(rand(49, 57));
            } else {
                $secret .= chr(rand(48, 57));
            }
        } else if (CHAR_WORD == $type) {
            $secret .= chr(rand(65, 90));
        } else {
            if (0 == $i) {
                $secret .= chr(rand(65, 90));
            } else {
                $secret .= (0 == rand(0, 1)) ? chr(rand(65, 90)) : chr(rand(48, 57));
            }
        }
    }
    return $secret;
}

/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pid parent标记字段
 * @param string $level level标记字段
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
{
    // 创建Tree
    $tree = array();
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] =& $list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] =& $list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent =& $refer[$parentId];
                    $parent[$child][] =& $list[$key];
                }
            }
        }
    }
    return $tree;
}

/**
 * 系统加密方法
 * @param string $data 要加密的字符串
 * @param string $key 加密密钥
 * @param int $expire 过期时间 单位 秒
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function think_encrypt($data, $key = '', $expire = 0)
{
    $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key);
    $data = base64_encode($data);
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    $str = sprintf('%010d', $expire ? $expire + time() : 0);

    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
    }
    return str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($str));
}

/**
 * 系统解密方法
 * @param string $data 要解密的字符串 （必须是think_encrypt方法加密的字符串）
 * @param string $key 加密密钥
 * @return string
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function think_decrypt($data, $key = '')
{
    $key = md5(empty($key) ? C('DATA_AUTH_KEY') : $key);
    $data = str_replace(array('-', '_'), array('+', '/'), $data);
    $mod4 = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    $data = base64_decode($data);
    $expire = substr($data, 0, 10);
    $data = substr($data, 10);

    if ($expire > 0 && $expire < time()) {
        return '';
    }
    $x = 0;
    $len = strlen($data);
    $l = strlen($key);
    $char = $str = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1)) < ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        } else {
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
}

// 可解密的md6
function md6($str = '', $de = false)
{
    $key = ('yourkey');
    $char = ('MDAwMDAwMDAwM');
    if ($str != '') {
        if ($de) {
            $str = $char . $str;
            $str = think_decrypt($str, $key);
        } else {
            $str = think_encrypt($str, $key);
            $str = str_replace($char, '', $str);
        }
    }
    return $str;
}

function GetHttpContent($fsock = null)
{
    $out = null;
    while ($buff = @fgets($fsock, 2048)) {
        $out .= $buff;
    }
    fclose($fsock);
    $pos = strpos($out, "\r\n\r\n");
    $head = substr($out, 0, $pos);    //http head
    $status = substr($head, 0, strpos($head, "\r\n"));    //http status line
    $body = substr($out, $pos + 4, strlen($out) - ($pos + 4));//page body

    if (preg_match("/^HTTP\/\d\.\d\s([\d]+)\s.*$/", $status, $matches)) {
        if (intval($matches[1]) / 100 == 2) {
            return $body;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

function DoGet($url)
{
    $url2 = parse_url($url);
    $url2["path"] = ($url2["path"] == "" ? "/" : $url2["path"]);
    $url2["port"] = ($url2["port"] == "" ? 80 : $url2["port"]);
    $host_ip = @gethostbyname($url2["host"]);
    $fsock_timeout = 2;  //2 second
    if (($fsock = fsockopen($host_ip, $url2['port'], $errno, $errstr, $fsock_timeout)) < 0) {
        return false;
    }
    $request = $url2["path"] . ($url2["query"] ? "?" . $url2["query"] : "");
    $in = "GET " . $request . " HTTP/1.0\r\n";
    $in .= "Accept: */*\r\n";
    $in .= "User-Agent: Payb-Agent\r\n";
    $in .= "Host: " . $url2["host"] . "\r\n";
    $in .= "Connection: Close\r\n\r\n";
    if (!@fwrite($fsock, $in, strlen($in))) {
        fclose($fsock);
        return false;
    }
    return GetHttpContent($fsock);
}

function DoPost($url, $post_data = array())
{
    $url2 = parse_url($url);
    $url2["path"] = ($url2["path"] == "" ? "/" : $url2["path"]);
    $url2["port"] = ($url2["port"] == "" ? 80 : $url2["port"]);
    $host_ip = @gethostbyname($url2["host"]);
    $fsock_timeout = 2; //2 second
    if (($fsock = fsockopen($host_ip, $url2['port'], $errno, $errstr, $fsock_timeout)) < 0) {
        return false;
    }
    $request = $url2["path"] . ($url2["query"] ? "?" . $url2["query"] : "");
    $post_data2 = http_build_query($post_data);
    $in = "POST " . $request . " HTTP/1.0\r\n";
    $in .= "Accept: */*\r\n";
    $in .= "Host: " . $url2["host"] . "\r\n";
    $in .= "User-Agent: Lowell-Agent\r\n";
    $in .= "Content-type: application/x-www-form-urlencoded\r\n";
    $in .= "Content-Length: " . strlen($post_data2) . "\r\n";
    $in .= "Connection: Close\r\n\r\n";
    $in .= $post_data2 . "\r\n\r\n";
    unset($post_data2);
    if (!@fwrite($fsock, $in, strlen($in))) {
        fclose($fsock);
        return false;
    }
    return GetHttpContent($fsock);
}

function HttpRequest($url, $data = array(), $header_data = [], $abort = false)
{
    if (!function_exists('curl_init')) {
        return empty($data) ? DoGet($url) : DoPost($url, $data);
    }
    $timeout = $abort ? 1 : 2;
    $ch = curl_init();

    if (is_array($data) && $data) {
        // $formdata = http_build_query($data);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
    }
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
    curl_setopt($ch, CURLOPT_HEADER, 0);

    if (!empty($header_data)) {
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header_data);
    } else {
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'cache-control: no-cache'
        ]);
    }

    $result = curl_exec($ch);
    return (false === $result && false == $abort) ? (empty($data) ? DoGet($url) : DoPost($url, $data)) : $result;
}

/**    缓存      **/
function setRedisByDb($k, $value = '', $expire = null, $db = 6)
{
    if (!env("ENABLE_REIDS")) return "";
    if (!$k) return "";

    $redis = app("redis");
    $redis->select($db);
    $value = (is_object($value) || is_array($value)) ? serialize($value) : $value;

    if ($expire > 0) {
        return $redis->setex($k, $expire, $value);
    } else {
        return $redis->set($k, $value);
    }
}

function redisExist($k)
{
    if (!env("ENABLE_REIDS")) return "";
    if (!$k) return "";
    return $redis = app("redis")->exist;
}


//获取
function getRedisByKey($k, $db = 6)
{
    if (!env("ENABLE_REIDS")) return "";

    if (!$k) return "";

    $redis = app("redis");
    $redis->select($db);
    $res = $redis->get($k);

    if (is_numeric($res))
        return $res;

    if ($res == false)
        return $res;

    return unserialize($res) !== null ? unserialize($res) : $res;
}

//删除
function delRedis($k, $db = 6)
{
    if (!$k) return;
    $redis = app("redis");
    $redis->select($db);

    return $redis->del(str_replace(env("REDIS_PREFIX"), "", $k));
}

function RecursiveMkdir($path)
{
    if (!file_exists($path)) {
        RecursiveMkdir(dirname($path));
        @mkdir($path, 0777);
    }
}

function calc_LCS($strArr1 = [], $strArr2 = [], $flag = true)
{

    $result = '';
    $com = '';

    for ($i = 0; $i < count($strArr1); $i++) {
        if ($flag && !in_array($strArr1[$i], $strArr2)) {
            return 0;
        }
        for ($j = 0; $j < count($strArr2); $j++) {
            if ($strArr1[$i] == $strArr2[$j]) {
                $result = $result . $strArr1[$i];
                if (!is_str_has($com, $strArr1[$i])) { //com 里有判断就为假就跳过，没有判断为真继续
                    if (substr_count($result, $strArr1[$i]) >= 2) { //result里包含的
                        $com = $com . $strArr1[$i];    //就缀到com里
                    }
                }
            }
        }
    }

    $arr_result = str_split_unicode($result);
    $len_result = count($arr_result);
    if (in_array('大', $arr_result)) {
        $len_result = bcsub($len_result, 0.7, 2);
    }
    if (in_array('师', $arr_result)) {
        $len_result = bcsub($len_result, 0.1, 2);
    }
    $arr_com = str_split_unicode($com);
    for ($i = 0; $i < count($arr_com); $i++) {
        $nums1 = substr_count(join(",", $strArr1), $arr_com[$i]);
        $nums2 = substr_count(join(",", $strArr2), $arr_com[$i]);
        $len_result = $len_result - $nums1 * $nums2 + min($nums1, $nums2);
    }
    if ($len_result <= 1) {
        $len_result = 0;
    }
    return $len_result;
}

function str_split_unicode($str, $l = 0)
{

    if ($l > 0) {
        $ret = array();
        $len = mb_strlen($str, "UTF-8");
        for ($i = 0; $i < $len; $i += $l) {
            $ret[] = mb_substr($str, $i, $l, "UTF-8");
        }
        return $ret;
    }

    return preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
}

function HumanTime($time = null, $forceDate = false)
{
    $now = time();
    $time = is_numeric($time) ? $time : strtotime($time);

    $interval = $now - $time;

    if ($forceDate || $interval > 30 * 86400) {
        return strftime("%Y-%m-%d %H:%M", $time);
    } else if ($interval > 86400) {
        $number = intval($interval / 86400);
        return "${number}天前";
    } else if ($interval > 3600) { // > 1 hour
        $number = intval($interval / 3600);
        return "${number}小时前";
    } else if ($interval >= 60) { // > 1 min
        $number = intval($interval / 60);
        return "${number}分钟前";
    } else if (5 >= $interval) {// < 5 second
        return "就在刚才";
    } else { // < 1 min
        return "${interval}秒前";
    }
}


function randIp()
{
    $ip_long = array(

        array('607649792', '608174079'), //36.56.0.0-36.63.255.255

        array('1038614528', '1039007743'), //61.232.0.0-61.237.255.255

        array('1783627776', '1784676351'), //106.80.0.0-106.95.255.255

        array('2035023872', '2035154943'), //121.76.0.0-121.77.255.255

        array('2078801920', '2079064063'), //123.232.0.0-123.235.255.255

        array('-1950089216', '-1948778497'), //139.196.0.0-139.215.255.255

        array('-1425539072', '-1425014785'), //171.8.0.0-171.15.255.255

        array('-1236271104', '-1235419137'), //182.80.0.0-182.92.255.255

        array('-770113536', '-768606209'), //210.25.0.0-210.47.255.255

        array('-569376768', '-564133889'), //222.16.0.0-222.95.255.255

    );

    $rand_key = mt_rand(0, 9);

    $ip = long2ip(mt_rand($ip_long[$rand_key][0], $ip_long[$rand_key][1]));

    $headers['CLIENT-IP'] = $ip;

    $headers['X-FORWARDED-FOR'] = $ip;

    $headerArr = array();

    foreach ($headers as $n => $v) {
        $headerArr[] = $n . ':' . $v;
    }

    return $headerArr;

}


if (!function_exists('curlHelper')) {

    /**
     * CURL请求
     *
     * @param string URL地址
     * @param mixed 请求方法,支持GET/POST/PUT/DELETE/PATCH/TRACE/OPTION/HEAD 默认GET
     * @param mixed 请求数据包体
     * @param mixed 请求头 数组
     * @param mixed 请求COOKIES字符串
     */
    function curlHelper($url, $method = 'GET', $data = null, $header = [], $cookies = "")
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_COOKIE, $cookies);
        switch ($method) {
            case "GET":
                curl_setopt($ch, CURLOPT_HTTPGET, true);
                break;
            case "POST":
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                break;
            case "PUT":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                break;
            case "DELETE":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                break;
            case "PATCH":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PATCH");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                break;
            case "TRACE":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "TRACE");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                break;
            case "OPTIONS":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "OPTIONS");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                break;
            case "HEAD":
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "HEAD");
                curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
                break;
            default:
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 1);
        curl_setopt($ch, CURLOPT_TIMEOUT, 3);   //只需要设置一个秒的数量就可以
        $response = curl_exec($ch);
        $output = [];
        $headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        // 根据头大小去获取头信息内容
        $output['header'] = substr($response, 0, $headerSize);
        $output['body'] = substr($response, $headerSize, strlen($response) - $headerSize);
        $output['detail'] = curl_getinfo($ch);
        curl_close($ch);
        return $output;
    }
}

if (!function_exists('getIPAddress')) {
    /**
     * @purpose 获取ip地址的物理地址
     *
     * $return 1-归属地  2- 运营商 3- 归属地+运营商  4: 经纬度
     *
     * @param string $ip
     * @return mixed|string
     */
    function getIPAddress($ip = '', $return = 1)
    {
        if (!$ip) {
            return '';
        }

        $res = DoGet("https://apis.map.qq.com/ws/location/v1/ip?key=CUNBZ-N7MR2-6EJUP-CAHQA-CGFLH-UWBE6&ip=" . $ip);
        $res = json_decode($res, true);
        if (!empty($res) && $res['status'] == 0) {
            if ($return == 4) {
                return $res['result']['location'] ?? null;
            }

            $address = $res['result']['ad_info'] ?? [];
            return $address;
        }

        $data = curlHelper('https://ipchaxun.com/' . $ip . '/', 'GET', [], [
            'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36',
        ]);

        $address = '';
        $operator = '';
        if ($data['body']) {
            if (preg_match('/<span class="name">归属地:<\/span><span class="value">(.*?)<\/span>/', $data['body'], $matches)) {
                $address = $matches[1];
            }
            if (preg_match('/<span class="name">运营商:<\/span><span class="value">(.*?)<\/span>/', $data['body'], $matches)) {
                $operator = $matches[1];
            }
        }

        if ($return == 1)
            return $address;
        elseif ($return == 2)
            return $operator;
        elseif ($return == 3)
            return $address . ' ' . $operator;
    }
}

function getbgqrcode($imageDefault, $textDefault, $background, $filename = "", $config = array())
{
    //如果要看报什么错，可以先注释调这个header
    if (empty($filename)) header("content-type: image/png");

    //背景方法
    $backgroundInfo = getimagesize($background);
    $ext = image_type_to_extension($backgroundInfo[2], false);
    $backgroundFun = 'imagecreatefrom' . $ext;
    $background = $backgroundFun($background);
    $backgroundWidth = imagesx($background);  //背景宽度
    $backgroundHeight = imagesy($background);  //背景高度
    $imageRes = imageCreatetruecolor($backgroundWidth, $backgroundHeight);
    $color = imagecolorallocate($imageRes, 0, 0, 0);
    imagefill($imageRes, 0, 0, $color);
    imagecopyresampled($imageRes, $background, 0, 0, 0, 0, imagesx($background), imagesy($background), imagesx($background), imagesy($background));

    //处理了图片
    if (!empty($config['image'])) {
        foreach ($config['image'] as $key => $val) {
            $val = array_merge($imageDefault, $val);
            $info = getimagesize($val['url']);
            $function = 'imagecreatefrom' . image_type_to_extension($info[2], false);
            if ($val['stream']) {
                //如果传的是字符串图像流
                $info = getimagesizefromstring($val['url']);
                $function = 'imagecreatefromstring';
            }

            $res = $function($val['url']);
            $resWidth = $info[0];
            $resHeight = $info[1];
            //建立画板 ，缩放图片至指定尺寸
            $canvas = imagecreatetruecolor($val['width'], $val['height']);
            imagefill($canvas, 0, 0, $color);
            //关键函数，参数（目标资源，源，目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h）
            imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'], $resWidth, $resHeight);
            $val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) - $val['width'] : $val['left'];
            $val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) - $val['height'] : $val['top'];

            //放置图像
            imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']);//左，上，右，下，宽度，高度，透明度
        }
    }

    //处理文字
    if (!empty($config['text'])) {
        foreach ($config['text'] as $key => $val) {
            $val = array_merge($textDefault, $val);

            list($R, $G, $B) = explode(',', $val['fontColor']);
            $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
            $val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) : $val['left'];
            $val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) : $val['top'];

            imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);

            if ($val['weight']) { //加粗
                for ($i = 0; $i < 10; $i++) {
                    imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
                }
            }
        }
    }

    //生成图片
    if (!empty($filename)) {
        $res = imagejpeg($imageRes, $filename, 90);
        //保存到本地
        imagedestroy($imageRes);
    } else {
        imagejpeg($imageRes);
        //在浏览器上显示
        imagedestroy($imageRes);
    }
}

function retSuc($data = [], $msg = 'ok', $code = 200)
{
    return (new ApiResponse(null))->success($data, $msg, $code);
}

function retFail($msg = 'error', $code = 400, $data = [])
{
    return (new ApiResponse(null))->error($msg, $code, $data);
}

//base64
function base64_to_jpeg($image, $img_name, $type = "png")
{
    $data = explode(",", $image);
    if (!$data[1]) return null;

    $date = date('Ymd');

    if (!$img_name) {
        $img_name = time() . rand(1000, 9999);
    }
    $n = $img_name . '.' . $type;

    //新建地址
    $img_root = str_replace('\\', '/', getcwd()) . '/Uploads/member/education';
    RecursiveMkdir($img_root . "/$date/");
    $path = $img_root . "/$date/{$n}";
    $real_path = "/Uploads/member/education/$date/{$n}";

    if (file_put_contents($path, base64_decode($data[1]))) {
        return $real_path;
    }

    return null;
}


function getUserAgent()
{
    $user_agent = $_SERVER['HTTP_USER_AGENT'];
// 判断是否为iOS设备
    $is_ios = preg_match('/(iPhone|iPad|iPod)/', $user_agent);
// 判断是否为安卓设备
    $is_android = preg_match('/Android/', $user_agent);
    if ($is_ios) {
        /*    echo "这是iOS手机";*/
        return 'ios';
    } elseif ($is_android) {
        /*echo "这是安卓手机";*/
        return 'android';
    } else {
        /*   echo "无法识别设备类型";*/
        return 'other';
    }
}

function get_short($str, $len, $ending = "...")
{
    $tempstr = csubstr($str, 0, $len);
    if ($str <> $tempstr) {
        $tempstr .= $ending;
    }
    return $tempstr;
}


function csubstr($str, $start, $len)
{
    $strlen = strlen($str);
    $clen = 0;
    for ($i = 0; $i < $strlen; $i++, $clen++) {
        if ($clen >= $start + $len) {
            break;
        }
        if (ord(substr($str, $i, 1)) > 0xa0) {
            if ($clen >= $start) {
                $tmpstr .= substr($str, $i, 3);
            }
            $i = $i + 2;
            $clen++;
        } else {
            if ($clen >= $start)
                $tmpstr .= substr($str, $i, 1);
        }
    }
    return $tmpstr;
}


/**
 * 获取url中的参数
 * @param $str
 * @param string $find
 */
function getUrlParams($str)
{
    $url = array_filter(explode("?", $str));

    if (count($url) == 1) {
        return ['url' => $url[0]];
    }

    $data['url'] = $url[0];
    $param_arr = array_filter(explode("&", $url[1]));
    $params = [];
    foreach ($param_arr as $k => $v) {
        $v = array_filter(explode("=", $v));
        if (empty($v)) continue;
        $params[$v[0]] = $v[1];
    }
    $data['params'] = $params;

    return $data;
}

/**
 * 格式化金额
 * @param int $price
 * @return int|void
 */
function formatNum($price = 0)
{
    if ($price < 1)
        return $price;

    if ($price == intval($price))
        return intval($price);

    $yu = $price - intval($price);
    if (round($yu, 2) == round($yu, 1)) {
        return intval($price) + round($yu, 1);
    }

    return round($price, 3);
}

/**
 * 获取周
 * @param null $date
 * @return string|null
 */
function getWeek($date = null)
{
    if (!$date)
        return null;

    $w = array('日', '一', '二', '三', '四', '五', '六');

    return '周' . $w[date('w', strtotime($date))];
}

function strlen_utf8($str)
{
    $i = 0;
    $count = 0;
    $len = strlen($str);
    while ($i < $len) {
        $chr = ord($str[$i]);
        $count++;
        $i++;
        if ($i >= $len) break;
        if ($chr & 0x80) {
            $chr <<= 1;
            while ($chr & 0x80) {
                $i++;
                $chr <<= 1;
            }
        }
    }
    return $count;
}


/**
 * 订单状态映射
 * @param $status
 * @return array
 */
function orderStatusMapping($status)
{
    if (!$status)
        return [];

    $filter = [];
    switch ($status) {
        case 60:
            $filter['status'] = [60, 61];
            break;
        case 17:
            $filter['status'] = 10;
            $filter['delivery_status'] = 20;
            $filter['deliver_status'] = 3;
            break;
        case 16:
            $filter['status'] = 10;
            $filter['delivery_status'] = 20;
            $filter['deliver_status'] = 2;
            break;
        case 12:
            $filter['status'] = 10;
            $filter['delivery_status'] = 10;
            break;
        case 11:
            $filter['status'] = 10;
            $filter['delivery_status'] = 0;
            break;
        default:
            $filter['status'] = $status;
            break;
    }

    return $filter;
}

/**
 * 订单当前状态
 * @param null $order
 * @return array|mixed|null
 */
function orderCurrentStatus($order = null)
{
    if (empty($order))
        return $order;

    if ($order['status'] == 10) {
        //配送状态
        if ($order['delivery_status'] == 20) {
            switch ($order['deliver_status']) {
                case 4:  //配送完成
                    $order['current_status'] = 20;
                    break;
                case 3:  //配送中
                    $order['current_status'] = 17;
                    break;
                case 2: //待配送
                    $order['current_status'] = 16;
                    break;
                default:
                    break;
            }
        } else if ($order['delivery_status'] == 10) {
            $order['current_status'] = 12; //出餐中
        } else {
            $order['current_status'] = 11; //待接单
        }
    } else if ($order['status'] == 61) {
        $order['current_status'] = 60;
    } else {
        $order['current_status'] = $order['status'];
    }

    return $order;
}

//预计送达时间
function deliverTimeRange($ctime = '', $etime = null, $interval = 60, $format = 'H:i')
{
    /*$arr = [
        "7:30-8:00",
        "8:30-9:00",
        "10:30-11:00",
        "11:30-12:00",
        "12:30-13:00",
        "13:30-14:00",
        "16:30-17:00",
        "17:30-18:00",
        "18:30-19:00",
        "19:30-20:00",
    ];*/
    $list = ParkDeliverTime::query()->where(['status' => 1])
        ->orderBy("sort", "desc")
        ->orderBy("end_time", "asc")
        ->get()
        ->toArray();

    $arr = [];
    foreach ($list as $k => $v) {
        if (empty($v['start_time']) || empty($v['end_time']))
            continue;

        $arr[$v['id']] = substr($v['start_time'], 0, 5) . '-' . substr($v['end_time'], 0, 5);
    }
    if (!$ctime)
        return $arr;

    $times = [];
    foreach ($arr as $k => $v) {
        $t = array_filter(explode("-", $v));
        if (strtotime($t[1]) <= strtotime($ctime) || (strtotime($t[0]) < strtotime($ctime) && strtotime($t[1]) > strtotime($ctime)))
            continue;
        if ($etime && strtotime($t[0]) > strtotime($etime)) {
            continue;
        }
        $times[] = $v;
    }

    return $times;
}

function deliver_timeList($v = '')
{
    $timesList = deliverTimeRange(null, null, 30);

    return isset($timesList[$v]) ? $timesList[$v] : null;
}


function getDeliveryTimes($ctime = null, $etime = null, $interval = 30)
{
    $timesList = deliverTimeRange($ctime, $etime, $interval);
    if (empty($timesList))
        return null;

    return $timesList;

    $timeRange = [];
    $stime = null;
    foreach ($timesList as $k => $v) {
        if ($k == 0) {
            $stime = $v;
            continue;
        }
        $timeRange[] = $stime . '-' . $v;
        $stime = $v;
        continue;
    }

    return $timeRange;
}


function objectToArray($object)
{
    if (empty($object) || count($object) == 0) {
        if (is_array($object)) {
            return array();
        } else {
            return trim((string)$object);
        }
    }

    $result = array();
    $object = is_object($object) ? get_object_vars($object) : $object;
    foreach ($object as $key => $val) {
        $val = (is_object($val) || is_array($val)) ? objectToArray($val) : $val;
        $result[$key] = $val;
    }
    return $result;
}


/**
 * 批量更新(更新条件的值只能是数子)
 * @param string $table_name :表名
 * @param array $data_arr :二维数组，注意 eg:[['id'=>88,'name'=>2222]] id是更新条件(更新条件不可以重复)
 * @param string $connection : 库名，不写就是默认的
 * @return bool|int
 */
function updateBatch($table_name = "", $data_arr = array(), $connection = '')
{

    if (empty($table_name) || empty($data_arr) || !is_array($data_arr) || empty($data_arr[0]) || !is_array($data_arr[0])) {
        return 0;
    }

    $update_column = array_keys($data_arr[0]);
    $where_column = $update_column[0]; //e.g id
    unset($update_column[0]);
    $whereIn = "";

    $q = "UPDATE " . $table_name . " SET ";
    foreach ($update_column as $u_column_v) {
        $q .= $u_column_v . " = CASE ";

        foreach ($data_arr as $data) {
            $q .= "WHEN " . $where_column . " = " . $data[$where_column] . " THEN '" . $data[$u_column_v] . "' ";
        }
        $q .= "ELSE " . $u_column_v . " END, ";
    }
    foreach ($data_arr as $data) {
        $whereIn .= "'" . $data[$where_column] . "', ";
    }
    $q = rtrim($q, ", ") . " WHERE " . $where_column . " IN (" . rtrim($whereIn, ', ') . ")";

    if (empty($connection)) {
        return DB::update(DB::raw($q));
    } else {
        return DB::connection($connection)->update(DB::raw($q));
    }
}

/**
 * 系统管理员
 * @param null $uid
 */
function checkIsSuper($uid = null)
{
    return (new UserRepository())->checkIsSuper($uid);
}

/**
 * 管理员关联店铺
 * @param null $uid
 */
function getUserRelateShopId($uid = null)
{
    return (new UserRepository())->getShopIdById(intval($uid ?? 0));
}

/**
 * 手机号加星
 * @param $phone
 * @return array|string|string[]
 */
function maskPhone($phone)
{
    if (empty($phone)) return null;
    return substr_replace($phone, '****', 3, 4);
}